# -*- coding: utf-8 -*-
# @Date：2024/7/30 22:19:23
# @Author：CJiaの青姝
# @FileName：dictType
# @Editor：PyCharm2024
# @Remark：
from typing import List, Any
from typing_extensions import Self

from data.models import Dict, DictType
from ninja import Router, Field, File, Query, ModelSchema
from ninja.files import UploadedFile
from ninja.pagination import paginate

from utils.serializes import model_dict_list
from utils.cj_ninja import CjFilters, MyPagination
from utils.cj_crud import create, batch_create, delete, batch_delete, update, condition, single
from utils.cj_export import export_data, parent_data, repeat_data, deal_chinese_key
from utils.cj_response import SuccessResponse, ErrorResponse

router = Router()


class Filters(CjFilters):
    name: str = Field(None, description="字典类型名称", alias='name')
    value: str = Field(None, description="字典类型值", alias='value')
    dicts_id: int = Field(None, description="字典ID", alias='dict_id')

    class Config:
        title = "字典类型查询参数"


class DictTypeSchemaIn(ModelSchema):
    dicts_id: int = Field(None, description="字典ID", alias='dict_id')

    def validate(cls, value: Any) -> Self:
        if value.name == '' or value.name is None:
            return "字典类型名称不能为空", 400
        elif value.value == '' or value.value is None:
            return "字典类型值不能为空", 400
        elif value.dicts_id == '' or value.dicts_id is None:
            return "字典id不能为空", 400
        # 返回请求数据
        return value, 200

    def model_validate(
            cls,
            obj: Any,
            *,
            strict: bool | None = None,
            from_attributes: bool | None = None,
            context: Any | None = None,
    ) -> Self:
        if obj.name == '' or obj.name is None:
            return "字典类型名称不能为空", 400
        elif obj.value == '' or obj.value is None:
            return "字典类型值不能为空", 400
        elif obj.dicts_id == '' or obj.dicts_id is None:
            return "字典id不能为空", 400
        # 判断重复
        if DictType.objects.filter(name=obj.name, dicts_id=obj.dicts_id).exists():
            return "同一字典下不能存在相同类型名称", 400
        # 返回请求数据
        return obj, 200

    class Config:
        title = '创建字典类型参数'
        model = DictType
        model_exclude = ['id', 'creator', 'modifier', 'create_time', 'update_time', 'dicts']


class DictTypeSchemaOut(ModelSchema):
    key: int = Field(None, description="唯一标识符", alias='key')

    class Config:
        title = '字段类型对象实例'
        model = DictType
        model_fields = "__all__"


@router.post("/dictType", summary="创建字典类型")
def create_dict_type(request, data: DictTypeSchemaIn):
    """ 创建字典类型 """
    message, code = data.model_validate(data)
    if code == 400:
        return ErrorResponse(msg=message)
    # 调用新增方法
    result = create(request, DictType, message)
    # 返回结果
    return SuccessResponse(data=result, msg="新增成功")


@router.post("/dictType/export", summary="导入字典类型")
def export_custom(request, file: UploadedFile = File(...)):
    """ 导入字典类型 """
    # 字段关系
    field_relations = {
        "字典类型名称": "name",
        "字典类型值": "value",
        "所属字典": "dicts_id",
    }
    # 检查字段
    check_list = ["字典类型名称", "字典类型值", "所属字典"]
    # 调用公共导入方法
    export_result = export_data(request, file, check_list)
    # 上级字段
    parent_list = [{"name": "所属字典", "field": "dicts_id", "model": "name"}]
    # 判断上级
    parent = parent_data(Dict, export_result['success'], parent_list)
    # 重复字段
    repeat_list = [{"name": "字典类型名称", "field": "name", "model": "name", "multiple": "所属字典",
                    "multiple_model": "dicts_id"}]
    # 判断重复
    result = repeat_data(DictType, parent['success'], repeat_list, True)
    # 处理中文key
    result = deal_chinese_key(result, field_relations)
    # 调用批量新增方法
    result_list = batch_create(request, DictType, result['success'])
    DictType.objects.bulk_create(result_list)
    message = f"成功导入{len(result_list)}条数据，失败信息{export_result['error'] + result['error'] + parent['error']}"
    # 返回结果
    return SuccessResponse(data=result['success'], msg=message)


@router.delete("/dictType/{dict_type_id}", response=DictTypeSchemaOut, summary="删除字典类型")
def delete_dict_type(request, dict_type_id: int):
    """ 删除字典类型 """
    # 调用删除方法
    result, code = delete(DictType, dict_type_id)
    if code != 200:
        return ErrorResponse(code=code, msg=result)
    # 返回结果
    return SuccessResponse(data=result, msg="删除成功")


@router.delete("/dictType/batch/del", summary="批量删除字典类型")
def batch_delete_dict_type(request, ids: List[int]):
    """ 批量删除字典类型 """
    # 调用批量删除方法
    result = batch_delete(request, DictType, ids)
    # 返回结果
    return SuccessResponse(data=result, msg="批量删除成功")


@router.put("/dictType/{dict_type_id}", response=DictTypeSchemaOut, summary="更新字典类型")
def update_dict(request, dict_type_id: int, data: DictTypeSchemaIn):
    """ 更新字典类型 """
    message, code = data.validate(data)
    if code == 400:
        return ErrorResponse(msg=message)
    # 判断重复
    if DictType.objects.filter(name=message.name, dicts_id=message.dicts_id).exclude(id=dict_type_id).exists():
        return ErrorResponse(msg="字典类型名称已存在，请重新输入")
    if DictType.objects.filter(value=message.value, dicts_id=message.dicts_id).exclude(id=dict_type_id).exists():
        return ErrorResponse(msg="字典类型值已存在，请重新输入")
    # 调用修改方法
    result = update(request, DictType, message, dict_type_id)
    # 返回结果
    return SuccessResponse(data=result, msg="更新成功")


@router.get("/dictType", response=List[DictTypeSchemaOut], summary="获取分页字典类型列表")
@paginate(MyPagination)
def list_custom(request, filters: Filters = Query(...)):
    """ 获取分页字段类型列表 """
    # 调用分页方法
    result = condition(request, DictType, filters)
    # 返回结果
    return result


@router.get("/dictType/dict/name", response=List[DictTypeSchemaOut], summary="根据字典名称获取字典类型列表")
def list_dict_name_type(request, dict_name: str = Query(...)):
    """ 根据字典名称获取字典类型列表 """
    # 根据名称获取字典id
    dict_id = Dict.objects.get(name=dict_name).id
    # 获取字典id字典类型列表
    dict_type_list = DictType.objects.filter(dicts_id=dict_id).values()
    # 将列表进行序列化
    result = model_dict_list(list(dict_type_list))
    # 返回结果
    return result


@router.get("/dictType/dict/{dict_id}", response=List[DictTypeSchemaOut], summary="获取分页字典id字典类型列表")
@paginate(MyPagination)
def list_dict_id_type(request, dict_id: int):
    """ 获取分页字典id字段类型列表 """
    # 获取字典id字典类型列表
    dict_type_list = DictType.objects.filter(dicts_id=dict_id).values()
    # 将列表进行序列化
    result = model_dict_list(list(dict_type_list))
    # 返回结果
    return result


@router.get("/dictType/{dict_type_id}", response=DictTypeSchemaOut, summary="获取字典类型")
def get_custom(request, dict_type_id: int):
    """ 获取字典类型 """
    # 调用根据id获取指定对象方法
    result = single(request, DictType, id=dict_type_id)
    # 返回结果
    return SuccessResponse(data=result)
